/*
 author:cyhu(viskey.hu@gmail.com) 2014.6.26
-- 2014.12.29 modify by cyhu

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:

 1. Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in
 the documentation and/or other materials provided with the distribution.

 3. The names of the authors may not be used to endorse or promote products
 derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**************************************************Constant**************************************************************/
var KEY_QTTS_SESSION_BEGIN          =     'qttssessionbegin';
	
var	KEY_QTTS_TEXT_PUT               =     'qttstextput';

var	KEY_QTTS_AUDIO_GET              =     'qttsaudioget';

var	KEY_QTTS_AUDIO_INFO             =     'qttsaudioinfo';

var KEY_QTTS_SESSION_END            =     'qttssessionend';

var KEY_QTTS_GET_PARAM              =     'qttsgetparam';

var KEY_QTTS_SET_PARAM              =     'qttssetparam';

var KEY_CONNECT                     =     'connect';

var KEY_DISCONNECT                  =     'disconnect';

var INTERVAL_AUDIO_GET              =      100;
/**************************************************Constant**************************************************************/
/***********************************************local Variables**********************************************************/
//record object
//var audioRecorder = new Recorder();
//var audioRecorder = null;

//session id
var session_id = null;

//get result function
var func_get_result = null;
//var func_display = null;

var synthesize_state = 'idle';

var text_ready = null;

//session begin params
var ssb_params = null;

var audioLen = 0;

var audioData = [];

var ced = 0;

//browser fingerprint id
var browser_id = new Fingerprint().get();

/* init audio context*/
var audioContext;

//audio link flag
var useLink = false;

//play function return
var funcPlay = null;

//是否第一次点击
var isFirst = true;
/***********************************************local Variables**********************************************************/

/**
* send session begin message
* varible : params_obj, object for session begin. such as usr, params , eg...
* varible : func
*/
function sessionBegin(params_obj, text, funcR)
{
    LOGCAT('send session begin');
	/* 对传入文本进行判空处理 */
	if(text == '' || text == undefined)
	{
		LOGCAT("传入文本为空");
		return;
	}
	
	regListener();
	
	params_obj.params = params_obj.params + ",browser_id=" + browser_id + ",host=" + document.domain + ",browser_sys="
	    + window.BrowserInfo.sys + ",browser_type=" + window.BrowserInfo.type;
	
	if(isFirst)
	{
		isFirst = false;
	    /* 若外部设定返回MP3或wav文件链接，则直接返回文件下载链接*/
	    if(params_obj.gat == 'mp3' || params_obj.gat == 'wav')
	    {
	        useLink = params_obj.gat;
	    /* 若该操作系统&浏览器类型仅支持播放MP3，则直接返回mp3下载链接*/
	    } else if(window.BrowserInfo.link == 'mp3') 
	    {
	        useLink = 'mp3';
	    }
		initFuncPlay();
		//window.socket.on(KEY_QTTS_AUDIO_GET, funcPlay);
		/* 用全局变量存储会话参数，为分次合成使用 */
	    ssb_params = params_obj;
	}	
	
	if(useLink == false)
    {
	    audioLen = 0;
	    audioData = [];
	    ced = 0;	
	} 

	text_ready = text;
	
	sendMessage(KEY_QTTS_SESSION_BEGIN, params_obj);
	func_get_result = funcR;
	
	synthesize_state = 'ssb';
	window.SessionInfo.errorcode = 0;
	window.SessionInfo.result = null;
}

function regListener()
{
	//var SOCKET_IO_URL = 'http://webapi.openspeech.cn:80/ivp' ;
    var SOCKET_IO_URL = window.Connection.socket_url;
	//console.log("2 : " + window.Connection.socket_url);
    window.socket = io.connect(SOCKET_IO_URL,  { 'reconnection': window.Connection.reconnection, 'reconnectionDelay':window.Connection.reconnectionDelay, 'force new connection': true });
	
   window.socket.on(KEY_QTTS_SESSION_BEGIN, function(obj) {

		var sessionid = obj.sessionid;
		var addonid = obj.addonID;
		var ret = obj.ret;
		LOGCAT("get session begin return : " + ret + ", sessionid : " + sessionid);
		if(ret == 0)
		{
			addon_id = addonid;
			session_id = sessionid;
			textPut();
		}
		else
		{
			return;
		}
	});	
	
	window.socket.on(KEY_QTTS_TEXT_PUT, function(ret) {
		LOGCAT("tts text put return : " + ret.ret);
		if( ret.ret == 0)
			audioGet(20);
		else
		{
			synthesize_state = 'sse';
			sessionEnd(50);
		}
	});
	
	window.socket.on(KEY_QTTS_AUDIO_GET, function(obj) {
	    if(useLink == false)
		{
			var audio_data = obj.audio_data;
			var err_code = obj.err_code;
			var synth_status = obj.synth_status;
			var audio_len = obj.audio_len;
			var audio_info = parseKey(obj.audio_info, "ced");
					
			if(err_code != 0 )
			{
				synthesize_state = 'sse';
				sessionEnd(50);
			} else {
				if(audio_len != 0)
				{					
					if(ced != audio_info && audioData.length > 0)
					{
					    LOGCAT("play part------------------" + ced + "-----------------------" + audio_info);
						func_get_result(err_code, {"audio_data" : audioData, "audio_len" : audioLen});
						audioData = [];
						audioLen = 0;
					}
							
					var i = 0;
					var int16Array = new Int16Array(audio_data);
					while(i < int16Array.length)
					{
						audioData[audioLen + i] = int16Array[i];
						i ++;
					}
					audioLen = audioLen + int16Array.length;
					ced = audio_info;
							
					if(synth_status == 2)
					{
						LOGCAT("synthesize status : 2");
						func_get_result(err_code, {"audio_data" : audioData, "audio_len" : audioLen});
						//audioData = [];
						//audioLen = 0;
								
						synthesize_state = 'sse';
						sessionEnd(50);
					} else {
						audioGet(10);
					}			
				} else {
					audioGet(10);
				}
						
					}
		} else {
			var err_code = obj.err_code;
			var synth_status = obj.synth_status;
			var audio_url = obj.audio_url;
			var duration = obj.duration;
		
			if(err_code != 0)
			{
				synthesize_state = 'sse';
				sessionEnd(0);
			} else if(synth_status == 2) 
			{
				if(audio_url != undefined)
					func_get_result(err_code, {"audio_url" : audio_url, "duration" : duration});
				synthesize_state = 'sse';
				sessionEnd(0);
			} else {
				audioGet(100);		
			}
		}
	});
	
	window.socket.on(KEY_QTTS_SESSION_END, function(obj) {
		LOGCAT("session end ,return value : " + obj);
		session_id = null;
	});	

	window.socket.on(KEY_QTTS_GET_PARAM, function(obj) {
		LOGCAT("get param ,return value : " + obj);
		
	});	

	window.socket.on(KEY_QTTS_SET_PARAM, function(obj) {
		LOGCAT("set param ,return value : " + obj);
	});
}

/**
* put text to synthesize
*/
function textPut()
{
    if(text_ready != null && text_ready.length > 0)
    {	
	    var message = {"addonid" : addon_id, "sessionid" : session_id, "text" : text_ready};
        sendMessage(KEY_QTTS_TEXT_PUT, message);
	}
}

/**
* get audio from server
* varible : wait_time, call getresult function after wait_time.
* varible : func
*/
function audioGet(wait_time)
{
	setTimeout('sendMessage(KEY_QTTS_AUDIO_GET, {"addonid" : addon_id, "sessionid" : session_id, "gat" : useLink})', wait_time);
}

/**
* session end, close the session
* varible : wait_time, call sessionend function after wait_time.
*/
function sessionEnd(wait_time)
{
	LOGCAT('synthesize_state : ' + synthesize_state + ', session_id : ' + session_id);
	if(synthesize_state == 'sse' && session_id != null)
	{
		setTimeout('sendMessage(KEY_QTTS_SESSION_END, {"addonid" : addon_id, "sessionid" : session_id})', wait_time);
	}
	synthesize_state = 'idle';
}

/**
* getparam from key
* varible : key , call getparam function
*/
function getParam(key)
{
    sendMessage(KEY_QISR_GET_PARAM, {"addon_id" : addon_id, "session_id" : session_id, "key" : key});
}

/**
* setparam from key
* varible : key 
* varible : value
*/
function setParam(key, value)
{
    sendMessage(KEY_QISR_SET_PARAM, {"addon_id" : addon_id, "session_id" : session_id, "key" : key, "value" : key});
} 

function parseKey(str, key)
{
	if(str == null || str == undefined)
	{
		return null;
	}
	
	if(str.indexOf("=") > 0 )
	{
		var values = str.split('=');
		if(values[0] == key)
		{
			return values[1];
		}
		else
		{
			return null;
		}
	}
	else
	{
		return null;
	}	
}

function initFuncPlay()
{
	if(useLink == false)
	{
		funcPlay = function(obj) {
			var audio_data = obj.audio_data;
			var err_code = obj.err_code;
			var synth_status = obj.synth_status;
			var audio_len = obj.audio_len;
			var audio_info = parseKey(obj.audio_info, "ced");
			
			if(err_code != 0 )
			{
				synthesize_state = 'sse';
				sessionEnd(50);
			} else {
				if(audio_len != 0)
				{					
					if(ced != audio_info && audioData.length > 0)
					{
						func_get_result(err_code, {"audio_data" : audioData, "audio_len" : audioLen});
						audioData = [];
						audioLen = 0;
					}
					
					var i = 0;
					var int16Array = new Int16Array(audio_data);
					while(i < int16Array.length)
					{
						audioData[audioLen + i] = int16Array[i];
						i ++;
					}
					audioLen = audioLen + int16Array.length;
					ced = audio_info;
					
					if(synth_status == 2)
					{
						LOGCAT("synthesize status : 2");
						func_get_result(err_code, {"audio_data" : audioData, "audio_len" : audioLen});
						audioData = [];
						audioLen = 0;
						
						synthesize_state = 'sse';
						sessionEnd(50);
					} else {
					    audioGet(100);
					}			
				} else {
				    audioGet(100);
				}
				
			}
		};	
	} else { 
	    funcPlay = function(obj) {
		   var err_code = obj.err_code;
		    var synth_status = obj.synth_status;
		    var audio_url = obj.audio_url;
		
		    if(err_code != 0)
		    {
			    synthesize_state = 'sse';
			    sessionEnd(0);
		    } else if(synth_status == 2) 
		    {
			    if(audio_url != undefined)
					func_get_result(err_code, {"audio_url" : audio_url, "duration" : obj.duration});
			    synthesize_state = 'sse';
			    sessionEnd(0);
		    } else {
			    audioGet(100);		
		    }
	    };
	}
}

sendMessage = function(filter, message)
{			
	window.socket.emit(filter, message);
};	
